﻿using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CoreNet.Swagger.Annotations
{
    public class AnnotationsDocumentFilter : IDocumentFilter
    {
       
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            if (swaggerDoc.Tags == null)
                swaggerDoc.Tags = new List<OpenApiTag>();

            var controllerNamesAndAttributes = context.ApiDescriptions
                .Select(apiDesc => apiDesc.ActionDescriptor as ControllerActionDescriptor)
                .Where(actionDesc => actionDesc != null)
                .GroupBy(actionDesc => actionDesc.ControllerName)
                .Select(group => new KeyValuePair<string, IEnumerable<object>>(group.Key, group.First().ControllerTypeInfo.GetCustomAttributes(true)));

            foreach (var entry in controllerNamesAndAttributes)
            {
                
                ApplySwaggerTagAttribute(swaggerDoc, entry.Key, entry.Value);
            }
        }

       

        private void ApplySwaggerTagAttribute(OpenApiDocument swaggerDoc,string controllerName,IEnumerable<object> customAttributes)
        {
            var swaggerTagAttribute = customAttributes
                .OfType<SwaggerTagAttribute>()
                .FirstOrDefault();

            if (swaggerTagAttribute == null) return;
            #region 懒猫添加

            var lst = swaggerDoc.Paths.Where(e => e.Key.Contains(controllerName)).ToList();
            foreach (var a in lst)
            {
                foreach (var b in a.Value.Operations)
                {
                    //b.Value.Tags
                    foreach (var c in b.Value.Tags)
                    {
                        c.Name = swaggerTagAttribute.Name;
                    }
                }
            }
            #endregion
            swaggerDoc.Tags.Add(new OpenApiTag
            {
                Name = string.IsNullOrEmpty(swaggerTagAttribute.Name) ? controllerName : swaggerTagAttribute.Name,
                Description = swaggerTagAttribute.Description,
                ExternalDocs = (swaggerTagAttribute.ExternalDocs != null)
                    ? new OpenApiExternalDocs { Url = new Uri(swaggerTagAttribute.ExternalDocs) }
                    : null
            });
            
        }
    }
}
